package com.dog.basics.service.mtkj.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dog.basics.bean.dto.admin.mtkj.CommonDiscountCouponFromDto;
import com.dog.basics.bean.dto.admin.mtkj.DiscountCouponAddDto;
import com.dog.basics.bean.dto.admin.mtkj.DiscountCouponEditDto;
import com.dog.basics.bean.dto.api.mtkj.ApiDiscountCouponAddDto;
import com.dog.basics.bean.dto.api.mtkj.ApiDiscountCouponEditDto;
import com.dog.basics.bean.model.mtkj.MtCoupon;
import com.dog.basics.bean.model.mtkj.MtDiscountCoupon;
import com.dog.basics.bean.model.mtkj.MtShopping;
import com.dog.basics.bean.vo.admin.mtkj.CommonDiscountCouponListVo;
import com.dog.basics.bean.vo.api.mtkj.ApiDeviceDiscountCouponVo;
import com.dog.basics.bean.vo.api.mtkj.ApiDiscountCouponListVo;
import com.dog.basics.common.util.CouponCodeUtil;
import com.dog.basics.common.util.PageParam;
import com.dog.basics.dao.mtkj.MtCouponMapper;
import com.dog.basics.dao.mtkj.MtDiscountCouponMapper;
import com.dog.basics.dao.mtkj.MtShoppingMapper;
import com.dog.basics.security.util.SecurityUtils;
import com.dog.basics.service.mtkj.IMtDiscountCouponService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 优惠券表 服务实现类
 * </p>
 *
 * @author wph
 * @since 2020-11-09
 */
@Service
@AllArgsConstructor
public class MtDiscountCouponServiceImpl extends ServiceImpl<MtDiscountCouponMapper, MtDiscountCoupon> implements IMtDiscountCouponService {

    private final MtCouponMapper couponMapper;
    private final MtShoppingMapper shoppingMapper;

    /**
     * 新增优惠券
     *
     * @param: addDto
     * @returns
     * @author hangdy
     * @date: 2020/11/13 9:42
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveDiscountCoupon(ApiDiscountCouponAddDto addDto) {
        MtDiscountCoupon discountCoupon = BeanUtil.copyProperties(addDto, MtDiscountCoupon.class);
        //查询商铺是否属于该用户
        MtShopping shop = shoppingMapper.selectById(addDto.getShopId());
        Validator.validateEqual(shop.getUserId(), SecurityUtils.getUser().getUserId(), "商铺信息不正确");

        discountCoupon.setCreateBy(SecurityUtils.getUser().getUserId());
        discountCoupon.setCreateTime(DateUtil.currentSeconds());
        //生成优惠券编码
        if (ObjectUtil.equal(addDto.getCouponType(), 0)) {
            discountCoupon.setDiscountCouponCode("YHQ" + CouponCodeUtil.getAtomicCounter());
        }

        //生成折扣券编码
        if (ObjectUtil.equal(addDto.getCouponType(), 1)) {
            discountCoupon.setDiscountCouponCode("ZKQ" + CouponCodeUtil.getAtomicCounter());
        }

        Validator.validateTrue(this.save(discountCoupon), "新增优惠券失败");

        return Boolean.TRUE;
    }

    /**
     * 修改优惠券
     * 1.由用户领取过的优惠券不能修改
     *
     * @param editDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editDiscountCoupon(ApiDiscountCouponEditDto editDto) {
        //查询优惠券是否存在
        MtDiscountCoupon discountCoupon = this.getById(editDto.getId());
        Validator.validateNotNull(discountCoupon, "优惠券不存在");
        //检查优惠券是否被用户领取
        List<MtCoupon> couponList = couponMapper.selectList(Wrappers.<MtCoupon>lambdaQuery()
                .eq(MtCoupon::getDiscountCouponId, editDto.getId()));

        if (couponList.size() != 0) {
            throw new RuntimeException("优惠券有用户领取不能修改");
        }

        //修改优惠券
        discountCoupon = BeanUtil.copyProperties(editDto, MtDiscountCoupon.class);
        discountCoupon.setUpdateBy(SecurityUtils.getUser().getUserId());
        discountCoupon.setUpdateTime(DateUtil.currentSeconds());

        Validator.validateTrue(this.updateById(discountCoupon), "优惠券修改失败");
        return Boolean.TRUE;
    }

    /**
     * 删除优惠券
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteDiscountCoupon(Long id) {
        MtDiscountCoupon discountCoupon = this.getById(id);
        Validator.validateNotNull(discountCoupon, "优惠券不存在");
        Validator.validateEqual(discountCoupon.getCreateBy(), SecurityUtils.getUser().getUserId(), "无法删除优惠券");
        //检查优惠券是否被用户领取
        List<MtCoupon> couponList = couponMapper.selectList(Wrappers.<MtCoupon>lambdaQuery()
                .eq(MtCoupon::getDiscountCouponId, id));

        if (couponList.size() != 0) {
            throw new RuntimeException("优惠券有用户领取不能修改");
        }

        Validator.validateTrue(this.removeById(id), "优惠券删除失败");
        return Boolean.TRUE;
    }

    /**
     * 查询商铺优惠券
     * 1.根据商铺id和状态查询兑换券
     *
     * @param shopId
     * @return
     */
    @Override
    public IPage<ApiDiscountCouponListVo> findByShopId(PageParam page, Long shopId) {
        //判断商铺是否存在
        MtShopping shopping = shoppingMapper.selectById(shopId);
        Validator.validateNotNull(shopping, "未找到商铺信息");

        IPage iPage = this.page(page, Wrappers.<MtDiscountCoupon>lambdaQuery()
                .eq(MtDiscountCoupon::getShopId, shopId)
                .eq(MtDiscountCoupon::getDelFlag, 0)
                .ge(MtDiscountCoupon::getDiscountCouponEndTime, DateUtil.currentSeconds())
        );

        List<MtDiscountCoupon> discountCouponList = iPage.getRecords();
        List<ApiDiscountCouponListVo> voList = discountCouponList.stream().map(e -> {
            ApiDiscountCouponListVo vo = BeanUtil.copyProperties(e, ApiDiscountCouponListVo.class);
            vo.setShopName(shopping.getName());
            List<MtCoupon> list = couponMapper.selectList(Wrappers.<MtCoupon>lambdaQuery().eq(MtCoupon::getDiscountCouponId, e.getId()).eq(MtCoupon::getUserId, SecurityUtils.getUser().getUserId()));
            if (CollUtil.isNotEmpty(list)) {
                vo.setSfUser(1);
            } else {
                vo.setSfUser(0);
            }

            return vo;
        }).collect(Collectors.toList());
        iPage.setRecords(voList);

        return iPage;
    }


    /**
     * admin服务
     * 生成通用优惠券
     * 超级管理员生成优惠券
     * 1.判断当前用户是否为超级管理员
     *
     * @param:
     * @returns
     * @author hangdy
     * @date: 2020/11/14 8:51
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveCommonDiscountCoupon(DiscountCouponAddDto dto) {

        MtDiscountCoupon discountCoupon = BeanUtil.copyProperties(dto, MtDiscountCoupon.class);
        discountCoupon.setShopId(-1L);
        //判断生成优惠券的开始时间大于等于结束时间生成失败
        if (dto.getDiscountCouponStartTime() >= dto.getDiscountCouponEndTime()) {
            throw new RuntimeException("开始时间不能大于等于结束时间");
        }
        //生成优惠券编码
        if (ObjectUtil.equal(dto.getCouponType(), 0)) {
            discountCoupon.setDiscountCouponCode("TYH" + CouponCodeUtil.getAtomicCounter());
        }

        //生成折扣券编码
        if (ObjectUtil.equal(dto.getCouponType(), 1)) {
            discountCoupon.setDiscountCouponCode("TZK" + CouponCodeUtil.getAtomicCounter());
        }
        discountCoupon.setType(1);
        discountCoupon.setCreateBy(SecurityUtils.getSysUser().getUserId());
        discountCoupon.setCreateTime(DateUtil.currentSeconds());
        Validator.validateTrue(this.save(discountCoupon), "优惠券生成失败");
        return Boolean.TRUE;
    }

    /**
     * admin服务
     * 修改通用优惠券
     * 1.只有超级管理员才能修改
     *
     * @param: editDto
     * @returns
     * @author hangdy
     * @date: 2020/11/14 9:50
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editCommonDiscountCoupon(DiscountCouponEditDto editDto) {

        //查询优惠券是否存在
        MtDiscountCoupon coupon = this.getById(editDto.getId());
        Validator.validateNotNull(coupon, "优惠券不存在");
        //检查优惠券是否被用户领取
/*        List<MtCoupon> couponList = couponMapper.selectList(Wrappers.<MtCoupon>lambdaQuery()
                .eq(MtCoupon::getDiscountCouponId,editDto.getId()));

        if(couponList.size() !=0){
            throw new RuntimeException("优惠券有用户领取不能修改");
        }*/
        MtDiscountCoupon discountCoupon = BeanUtil.copyProperties(editDto, MtDiscountCoupon.class);
        //判断生成优惠券的开始时间大于等于结束时间生成失败
        if (editDto.getDiscountCouponStartTime() >= editDto.getDiscountCouponEndTime()) {
            throw new RuntimeException("开始时间不能大于等于结束时间");
        }
        discountCoupon.setType(1);
        discountCoupon.setUpdateBy(SecurityUtils.getSysUser().getUserId());
        discountCoupon.setUpdateTime(DateUtil.currentSeconds());

        Validator.validateTrue(this.updateById(discountCoupon), "修改失败");
        return Boolean.TRUE;
    }

    /**
     * admin服务
     * 超级管理员删除优惠券
     *
     * @param: id
     * @returns
     * @author hangdy
     * @date: 2020/11/14 10:56
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteDiscountCouponByAdmin(Long id) {

        MtDiscountCoupon discountCoupon = this.getById(id);
        Validator.validateNotNull(discountCoupon, "优惠券不存在");
        //检查优惠券是否被用户领取
/*        List<MtCoupon> couponList = couponMapper.selectList(Wrappers.<MtCoupon>lambdaQuery()
                .eq(MtCoupon::getDiscountCouponId,id));

        if(couponList.size() !=0){
            throw new RuntimeException("优惠券有用户领取不能修改");
        }*/

        //目前没有做权限处理
        Validator.validateTrue(this.removeById(id), "删除失败");
        return Boolean.TRUE;
    }

    /**
     * admin服务
     * 查询优惠券（包括通用优惠券）
     *
     * @param page
     * @param fromDto
     * @return
     */
    @Override
    public IPage<CommonDiscountCouponListVo> findDiscountCoupon(PageParam page, CommonDiscountCouponFromDto fromDto) {

        IPage iPage = this.page(page, Wrappers.<MtDiscountCoupon>lambdaQuery()
                //根据面额查询
                .like(ObjectUtil.isNotNull(fromDto.getDiscountCouponValue()), MtDiscountCoupon::getDiscountCouponValue, fromDto.getDiscountCouponName())
                //根据最低消费查询
                .like(ObjectUtil.isNotNull(fromDto.getMinimumConsumption()), MtDiscountCoupon::getMinimumConsumption, fromDto.getMinimumConsumption())
                //根据优惠券类型查询0:满减 1:折扣
                .eq(ObjectUtil.isNotNull(fromDto.getCouponType()), MtDiscountCoupon::getCouponType, fromDto.getCouponType())
                //根据折扣查询
                .eq(ObjectUtil.isNotNull(fromDto.getDiscount()), MtDiscountCoupon::getDiscount, fromDto.getDiscount())
                //根据优惠券名称查询
                .like(ObjectUtil.isNotNull(fromDto.getDiscountCouponName()), MtDiscountCoupon::getDiscountCouponName, fromDto.getDiscountCouponName())
                //根据优惠券描述
                .like(ObjectUtil.isNotNull(fromDto.getContent()), MtDiscountCoupon::getContent, fromDto.getContent())
                .eq(MtDiscountCoupon::getType, 1)
                .orderByDesc(MtDiscountCoupon::getCreateTime)

        );

        List<MtDiscountCoupon> discountCouponList = iPage.getRecords();
        List<CommonDiscountCouponListVo> couponListVos = discountCouponList.stream().map(e -> {
            CommonDiscountCouponListVo vo = BeanUtil.copyProperties(e, CommonDiscountCouponListVo.class);
            return vo;

        }).collect(Collectors.toList());

        iPage.setRecords(couponListVos);

        return iPage;
    }

    /**
     * admin服务
     * 查询优惠券通用优惠券APP
     *
     * @param: page
     * @param: fromDto
     * @returns
     * @author hangdy
     * @date: 2020/11/14 10:10
     */
    @Override
    public IPage<ApiDeviceDiscountCouponVo> findAppDiscountCoupon(PageParam page) {

        IPage iPage = this.page(page, Wrappers.<MtDiscountCoupon>lambdaQuery()
                .eq(MtDiscountCoupon::getType, 1)
                .orderByDesc(MtDiscountCoupon::getCreateTime)

        );

        List<MtDiscountCoupon> discountCouponList = iPage.getRecords();
        List<ApiDeviceDiscountCouponVo> couponListVos = discountCouponList.stream().map(e -> {
            ApiDeviceDiscountCouponVo vo = BeanUtil.copyProperties(e, ApiDeviceDiscountCouponVo.class);
            List<MtCoupon> list = couponMapper.selectList(Wrappers.<MtCoupon>lambdaQuery().eq(MtCoupon::getDiscountCouponId, e.getId()).eq(MtCoupon::getUserId, SecurityUtils.getUser().getUserId()));
            if (CollUtil.isNotEmpty(list)) {
                vo.setSfUser(1);
            } else {
                vo.setSfUser(0);
            }

            return vo;
        }).collect(Collectors.toList());

        iPage.setRecords(couponListVos);

        return iPage;
    }

}
